<?php

namespace StarCloud\Services;

use StarCloud\Library\FastRank;
use StarCloud\Library\HashRedis;

abstract class FastRankService extends BaseService
{
    const TYPE_RANK = 1;
    const TYPE_HASH = 2;
    public static function addMemberToRank($rankName, $uid, $score)
    {
        FastRank::instance(static::createRankKey($rankName, self::TYPE_RANK))->addMemberToRank($score, $uid);
    }

    public static function incrMemberScoreToRank($rankName, $uid, $incrScore = 1)
    {
        FastRank::instance(static::createRankKey($rankName, self::TYPE_RANK))->incrMemberScoreToRank($incrScore, $uid);
    }

    public static function getMemberScore($rankName, $uid)
    {
        return (int) FastRank::instance(static::createRankKey($rankName, self::TYPE_RANK))->getMemberScore($uid);
    }

    public static function getMemberRank($rankName, $uid)
    {
        return (int) FastRank::instance(static::createRankKey($rankName, self::TYPE_RANK))->getMemberRank(PHP_INT_MAX, $uid);
    }

    public static function getRank($rankName, $limit)
    {
        $result = [];
        foreach (FastRank::instance(static::createRankKey($rankName, self::TYPE_RANK))->getRank(1, $limit) as $uid => $score) {
            $result[] = ['uid' => (int) $uid, 'score' => (int) $score];
        }

        return $result;
    }

    public static function getScoreByRank($rankName, $rank)
    {
        if ($rank <= 0) {
            $rank = 1;
        }

        $result = FastRank::instance(static::createRankKey($rankName, self::TYPE_RANK))->getRank($rank, $rank);
        $result = array_values($result);
        return isset($result[0]) ? $result[0] : 0;
    }

    public static function hIncrBy($rankName, $uid)
    {
        return HashRedis::instance(static::createRankKey($rankName, self::TYPE_HASH))->hIncrBy($uid);
    }

    public static function hSet($rankName, $uid, $value)
    {
        HashRedis::instance(static::createRankKey($rankName, self::TYPE_HASH))->hSet($uid, $value);
    }

    public static function hGet($rankName, $uid)
    {
        return HashRedis::instance(static::createRankKey($rankName, self::TYPE_HASH))->hGet($uid);
    }

    public static function hMGet($rankName, $uids)
    {
        return HashRedis::instance(static::createRankKey($rankName, self::TYPE_HASH))->hMGet($uids);
    }

    public static function hExists($rankName, $uid)
    {
        return HashRedis::instance(static::createRankKey($rankName, self::TYPE_HASH))->hExists($uid);
    }

    abstract public static function createRankKey($rankName, $type);
}
